
Earlier this year, I spent a lot of time working through a ton of apps for Ubuntu Touch that were "left behind" on Xenial, and updated them to Focal, and most of those to Noble, for the new UT system. However, one of the apps I really, really wanted to update was called Kaidan, which you can check out the original click[1] or look at their official website[2] for reference, but it is a cross platform app for XMPP messaging. For some odd reason, there is actually only one XMPP app for Ubuntu Touch, and it is a web app which only works with XMPP servers that support BOSH, which doesn't happen to be any of the servers I currently use, nor any I really know of. So, that means there were no XMPP apps on Ubuntu Touch that I could use. I suppose that shouldn't be so strange, but Linux geeks tend to use high security protocols like XMPP with encryption, either PGP or OMEMO, so it struck me as strange that there wasn't an app/click available to do this.
Either way, at the time (going through the 200 "left behind" apps), the project was too big for me to take on. I didn't have the time nor the experience to work on it. So, I set it aside and continued work on the other couple hundred apps instead. But, once I finished that, I decided to come back to Kaidan and see what could be done with it, as it was "near and dear" to my heart, as an app that I would actually use on a daily basis. The original app was version 0.4.2, and since then, Kaidan is up to version 0.13.x, so it was pretty far behind. After some digging, I found some posts where the original developers dropped Ubuntu Touch support because UT didn't keep up with the current versions of QT. Xenial was woefully behind on the QT front, but in my case, updating to Focal, it was still behind the times, but meant that I could update the Kaidan app to version 0.6.0. I couldn't go any newer, because 0.7.0 switched to QT 5.15+, and Focal was stuck on QT 5.12.
With a download of the latest workable version, 0.6.0, I had a pretty big task at hand, and had to get some help along the way. I want to be really clear, I have zero real programming skills, and barely any experience on how to do this, but I was willing to roll up my sleeves and get it wrong a time or two until something worked. The first thing I had to do was find and update the 3rd party libraries, like ZXing-cpp and such[3]. The normal available libraries packaged as debs in Ubuntu were not the correct version on Focal for this app. Then I had to update the custom build scripts from 0.4.2 to 0.6.0 and from Xenial to Focal[4]. At this point, I had a buildable click package, that didn't really work, but it did launch! Unfortunately, a lot of stuff was missing, so I had to add the Breeze icons[5] and the QXMPP library[6] as well. It seems pretty simple to mention here, but it took a long time to figure out which exact commit in those libraries to go back to and download to use for this click, since I couldn't use the latest and greatest version, because it has changed so much in the years since this app was written.
One of the major problems with the app itself, at this point, was that tapping on the text input field, to type a new message, caused the whole screen to fly upwards. This made it impossible to see what you were typing, so you just had to type blindly, and hit send, hoping you didn't make a spelling mistake. I would note that the original 0.4.2 click in the open store also had this "bug" listed by several users. This is the first place I enlisted some help. A friendly person known as "Soscat House" on the UT app development channel was interested in seeing the work I was tyring to do on Kaidan, and they asked if they could fork it. Being very open source friendly, I said sure, and they implemented a (in their own words) hacky way to fix the keyboard[7]. They also implemented a few theme changes, but I ended up having to revert those[8] because it didn't work quite right. The gist of the keyboard hack was this, which I implemented in other places as well[9]:
property real savedHeight: 0
// Debug: Monitor keyboard and page changes
Connections {
target: Qt.inputMethod
function onKeyboardRectangleChanged() {
console.log("=== KEYBOARD CHANGED ===")
console.log("Keyboard Rectangle:", Qt.inputMethod.keyboardRectangle)
console.log("Keyboard Y:", Qt.inputMethod.keyboardRectangle.y)
console.log("Keyboard Height:", Qt.inputMethod.keyboardRectangle.height)
console.log("Keyboard Visible:", Qt.inputMethod.visible)
console.log("Page Height:", root.height)
console.log("Page Y:", root.y)
console.log("Window Height:", applicationWindow().height)
}
}
onHeightChanged: {
console.log(">>> PAGE HEIGHT CHANGED:", height)
// Set fixed height when keyboard is visible
if (Qt.inputMethod.visible && height !== 500) {
console.log(">>> SETTING FIXED HEIGHT: 400")
height = 400
}
// Save original height when keyboard is not visible
else if (!Qt.inputMethod.visible && height > 500) {
savedHeight = height
console.log(">>> SAVED ORIGINAL HEIGHT:", savedHeight)
}
// Restore original height when keyboard disappears
else if (!Qt.inputMethod.visible && savedHeight > 0 && height !== savedHeight) {
console.log(">>> RESTORING ORIGINAL HEIGHT:", savedHeight)
height = savedHeight
}
}
onYChanged: {
console.log(">>> PAGE Y CHANGED:", y)
}
I know this is not right, but it was a quick fix that did the trick. I just put this on any QML page that required me to type anything. This essentially keeps the screen from flying upwards by making it "smaller". The normal height when the keyboard pops up is 730~ on my phone, and since that height is above 500, the settings for the page get set back down to a fixed height of 400, which brings the screen back down to past the middle. This allows you to see what you are typing. Originally Soscat had made it 500, but I thought 400 looked more natural, placing the text bar just above the keyboard, like you would expect on Android or IOS.
What followed next was a lot of work where I tried to make the built in methods for taking pictures, recording audio, and sending files work. Unfortunately, it was slow going, but after careful thought, I realized I needed to abandon that approach. The built in methods were not right for Ubuntu Touch, because that's not how most apps on UT work. In UT, if you want to upload a file, you don't have a file uploader, you use the content hub to send a file from the file manager. Likewise, if you want to take a picture and send it to someone on UT, you don't have a built in picture taking method, you use the content hub and choose the camera, which will allow you to take a picture with the normal UT camera app, and then it gets sent to the app you are useing. So, I ended up removing a lot of code to the media importing buttons and picture taking popups, and audio recording gui, etc., and instead implemented the content hub[10]. Implementing it took numerous commits and multiple tries, because I had a lack of knowledge on how to get it done propperly, but in the end, and as you can see by the commit name, praise God, I was able to fix the media import function to take the file from the content hub and send it to a recipient[11]!
Of course, in between I was fixing icons that didn't show up and editing fields that were displaying wrong, etc. Lots of little commits that I wont bore you with here, but you are welcome to check out on my repository[12]. SOme of the other fixes were related to the XMPP servers for creating a new account. At first I updated the servers list to be current, but in the end realized that over time it would change a lot, so I ditched the whole servers inline setup process, and just made it so you had to log in for the first time with your already created account. There are plenty of places to do that online, or on a desktop as well, so I didn't feel this was a huge loss, but maintaining an up to date list with propper links was going to be really tedious.
I also worked on the camera view for adding your account with the built in QR code scanner, but it had so many issues (most likely due to my complete inexperience) that I decided to drop it, which actually made the app seem more coherent with UT, as the impementation didn't seem to "fit" with how things look or work normally in Ubuntu Touch, it just felt like an add on, and while I could make it work, the user experience was poor. Then I moved on to working on notifications, but it already has a notification ability, just not working in UT, so I decided to table that for future releases instead of fighting that battle on 0.6.0. Last but not least was figuring out the light/dark mode for the UI. In Ubuntu Touch, the user can select dark mode system wide, and all apps are supposed to comply by having a dark background and light forground. But, in Kaidan, when you chose dark mode, the words because white, but the background stayed white, so you couldn't read anything!
At first, I implemented this code:
// If using QT_QUICK_CONTROLS_STYLE as Material, use this for Light and Dark
qputenv("QT_QUICK_CONTROLS_MATERIAL_THEME", QByteArray("Light"));
// TODO make this work on OSs other than Ubuntu Touch
QString settingsFile = QStringLiteral("%1/lomiri-ui-toolkit/theme.ini");
QString ubuntuDarkTheme = QStringLiteral("Lomiri.Components.Themes.SuruDark");
QSettings settings(settingsFile.arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)), QSettings::IniFormat);
QString themeName = settings.value(QStringLiteral("theme")).toString();
if (themeName == ubuntuDarkTheme) {
qDebug() << "Theme is dark.";
qputenv("QT_QUICK_CONTROLS_MATERIAL_THEME", QByteArray("Dark"));
}
Which worked great on the desktop, when I run the app on the computer with clickable desktop --dark-mode. The app turns dark background, the status bar turns green instead of gray, and the text becomes off white, making a perfect dark mode. Unfortunately, it didn't do that when it was on the phone. Instead it would just do the usual light background with light text, making it impossible to read. I didn't want to spend too much effort on making a dark mode, but at the same time, I didn't want users who selected dark mode system wide to have a non-functional app. So I implemented this code to prevent it from switching:
QQuickStyle::setStyle(QStringLiteral("org.kde.desktop"));
For some reason, this one liner prevents it from switching from light to dark mode. So if the whole system is globally set to dark mode, this app still shows up light. Thus, dark mode users may be unhappy about it not being dark mode, but at least they can still use the app! With all that done, I was finally ready for testing, so I released it to the UT QA testing group for review and testing. My plan is to let it run for a week before releasing the app. Fortunately for me, I was able to talk with the official Kaidan developers, and they were super helpful, and very encouraging. They gave me permission to release my rework of their app under the Kaidan name, so I don't have to fork their work and name it something else. I do have to be really clear that this is an older version of Kaidan, so that users are not confused by the lack of newer features. One of the biggest features missing from 0.6.0 is OMEMO support, and that is why I am working on a newer version for Noble, which has that built in!
Linux - keep it simple.
[1] Kaidan on the open-store [2] Kaidan.im [3] Commit: Update 3rd party for Focal and 060 for UT [4] Commit: Updates for Focal [5] Commit: Add Breeze icons [6] Commit: Add QXMPP [7] Commit: Soscat keyboard fix [8] Commit: Revert theme changes [9] Commit: Fix keyboard in other places [10] Commit: Added content hub [11] Commit: Fixed mediaimport! Praise God! [12] kaidan_0_6_0 repository